﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuaInterface;
using NTUTMessagerAPI;

namespace NTUTMessagerServer
{
    public class NetworkModel
    {
        public MemberModel memberModel;
        public FriendModel friendModel;
        public LoginModel loginModel;
        public SocketAPI socketApi;

        public void initialize() 
        {
            memberModel = new MemberModel();
            memberModel.LoadMember();

            friendModel = new FriendModel();
            loginModel = new LoginModel();
            socketApi = new SocketAPI();

            socketApi.BeginListen();
            socketApi.ConnectListAddEvent += ConnectEvent;
            socketApi.GetCommandEvent += GetCommand;
            socketApi.ConnectListRemoveEvent += disconnect;

        }

        public void disconnect(ConnectPair pair) 
        {
           LoginEntry entry = loginModel.RemoveLoginEntry(pair.address);

           if (entry != null) 
           {
               NoticeFriend(false, entry);
           }


        }

        public void GetCommand(ConnectPair pair, String command) 
        {
            Lua lua = new Lua();

            lua.DoString(command);

            FriendMethod(pair, lua);
            LoginMethod(pair, lua);

        }

        private void FriendMethod(ConnectPair pair, Lua lua)
        {
            LuaTable getFriend = lua.GetTable("getFriend");

            if (getFriend != null)
            {
                String account = (String)pair.UserData;
                FriendList friendList = friendModel.getFriend(account);

                List<LoginEntry> result = new List<LoginEntry>();

                foreach (String friend in friendList.Friends)
                {
                    LoginEntry loginEntry = loginModel.isOnline(friend);
                    if (loginEntry == null)
                    {
                        loginEntry = new LoginEntry();
                        loginEntry.account = friend;
                        loginEntry.ReportIp = "none";
                        loginEntry.publicKey = "none";
                    }

                    result.Add(loginEntry);
                }

                String table = "FriendTable = {";
                foreach(LoginEntry loginEntry in result)
                {
                    table += "{ [\"account\"] = \"" + loginEntry.account + "\" , [\"ip\"] = \"" + loginEntry.ReportIp + "\" , [\"publicKey\"] = \"" + loginEntry .publicKey+ "\" , }  ,";
                }           

                table += "}";

                socketApi.SendCommand(pair, table);
            }
        }

        private void LoginMethod(ConnectPair pair, Lua lua)
        {
            LuaTable loginTable = lua.GetTable("loginTable");

            if (loginTable != null)
            {
                string account = loginTable["account"].ToString();
                string password = loginTable["password"].ToString();
                string publicKey = loginTable["publicKey"].ToString();


                string ip = loginTable["ip"].ToString();

                pair.UserData = account;

                Boolean isCorrect = memberModel.isValidate(account, password);


                if (isCorrect)
                {
                    LoginEntry entry = null;
                    entry = loginModel.AddLoginEntry(account, ip, pair.address, publicKey);
                    NoticeFriend(true, entry);
                }

                socketApi.SendCommand(pair, "loginResult = { [\"result\"] =" + isCorrect.ToString().ToLower() + "}");

               
            }
        }

        public void NoticeFriend(Boolean UpOrDown, LoginEntry loginEntry) 
        {
            FriendList list = friendModel.getFriend(loginEntry.account);

           foreach (String friend in list.Friends) 
           {
               LoginEntry entry = loginModel.isOnline(friend);

               if (entry!=null) 
               {
                   String OnlineCommand;

                   if (UpOrDown)
                   {
                       OnlineCommand = "FriendStateTable = { [\"account\"] = \"" + loginEntry.account + "\" , [\"ip\"] = \"" + loginEntry.ReportIp + "\" , [\"publicKey\"] = \"" + loginEntry.publicKey + "\" , } ";
                   }
                   else 
                   {
                       OnlineCommand = "FriendStateTable = { [\"account\"] = \"" + loginEntry.account + "\" , [\"ip\"] = \"none\" , [\"publicKey\"] = \"none\" , } ";
                   }


                   socketApi.SendCommand(System.Net.IPAddress.Parse(entry.RealIp), OnlineCommand);
               }
           }
        }

        public void ConnectEvent(ConnectPair p) 
        {
            Console.WriteLine("Someone Connected :" + p.address);
            socketApi.Send_Diffie_Hellman(p,new Random().Next(100));
        }

    

        public void InvokeYourFriends(string account)
        {

        }

        public void SendUserFriendLoginStatus(string account)
        {

        }

        
        
    }
}
